/* eslint-disable no-nested-ternary */
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/**
 * num 小于0，左缩进num*2个空格； 大于0，右缩进num*2个空格。
 * @param {string} str 代码
 * @param {number} num 缩进次数
 * @param {number} len 【可选】缩进单位，空格数
 */
export function indent(str, num, len = 2) {
	if (num === 0) return str
	const isLeft = num < 0;
	const result = [];
	let reg;
	let
		spaces = ''
	if (isLeft) {
		num *= -1
		reg = new RegExp(`(^\\s{0,${num * len}})`, 'g')
	} else {
		for (let i = 0; i < num * len; i++) spaces += ' '
	}

	str.split('\n').forEach(line => {
		line = isLeft ? line.replace(reg, '') : spaces + line
		result.push(line)
	})
	return result.join('\n')
}

// 首字母大小
export function titleCase(str) {
	return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
}

// 下划转驼峰
export function camelCase(str) {
	return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
}

export function isNumberStr(str) {
	return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}

export const exportDefault = 'export default '

export const beautifierConf = {
	html: {
		indent_size: '2',
		indent_char: ' ',
		max_preserve_newlines: '-1',
		preserve_newlines: false,
		keep_array_indentation: false,
		break_chained_methods: false,
		indent_scripts: 'separate',
		brace_style: 'end-expand',
		space_before_conditional: true,
		unescape_strings: false,
		jslint_happy: false,
		end_with_newline: true,
		wrap_line_length: '110',
		indent_inner_html: true,
		comma_first: false,
		e4x: true,
		indent_empty_lines: true
	},
	js: {
		indent_size: '2',
		indent_char: ' ',
		max_preserve_newlines: '-1',
		preserve_newlines: false,
		keep_array_indentation: false,
		break_chained_methods: false,
		indent_scripts: 'normal',
		brace_style: 'end-expand',
		space_before_conditional: true,
		unescape_strings: false,
		jslint_happy: true,
		end_with_newline: true,
		wrap_line_length: '110',
		indent_inner_html: true,
		comma_first: false,
		e4x: true,
		indent_empty_lines: true
	}
}

function stringify(obj) {
	return JSON.stringify(obj, (key, val) => {
		if (typeof val === 'function') {
			return `${val}`
		}
		return val
	})
}

function parse(str) {
	JSON.parse(str, (k, v) => {
		if (v.indexOf && v.indexOf('function') > -1) {
			return eval(`(${v})`)
		}
		return v
	})
}

export function jsonClone(obj) {
	return parse(stringify(obj))
}

// 深拷贝对象
export function deepClone(obj) {
	const _toString = Object.prototype.toString

	// null, undefined, non-object, function
	if (!obj || typeof obj !== 'object') {
		return obj
	}

	// DOM Node
	if (obj.nodeType && 'cloneNode' in obj) {
		return obj.cloneNode(true)
	}

	// Date
	if (_toString.call(obj) === '[object Date]') {
		return new Date(obj.getTime())
	}

	// RegExp
	if (_toString.call(obj) === '[object RegExp]') {
		const flags = []
		if (obj.global) {
			flags.push('g')
		}
		if (obj.multiline) {
			flags.push('m')
		}
		if (obj.ignoreCase) {
			flags.push('i')
		}

		return new RegExp(obj.source, flags.join(''))
	}

	const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}

	for (const key in obj) {
		result[key] = deepClone(obj[key])
	}

	return result
}
/**
 * 将用户输入的连续单个数字合并为一个数
 * @param {Array} expressions - 记录计算表达式的数组
 * @returns {Array} 新的数组
 */
export const mergeNumberOfExps = expressions => {
	const res = []
	const isNumChar = n => /^[\d|\.]$/.test(n)
	for (let i = 0; i < expressions.length; i++) {
		if (i > 0 && isNumChar(expressions[i - 1]) && isNumChar(expressions[i])) {
			res[res.length - 1] += expressions[i]
			continue
		}
		res.push(expressions[i])
	}
	return res
}
/**
 * 校验表达式是否符合计算法则
 * @param {Array} expressions - 合并数字后的表达式数组
 * @returns {Boolean}
 */
export const validExp = (expressions, mergeNum = true) => {
	const temp = mergeNum ? mergeNumberOfExps(expressions) : expressions
	const arr = temp.filter(t => !'()'.includes(t))
	// 去括号后 length应该为奇数  并且第一个字符和最后一个字符应该为数字而非计算符号
	if (temp.length % 2 === 0 || arr.length % 2 === 0 || Number.isNaN(+arr[0]) || Number.isNaN(+arr[arr.length -
			1])) {
		return false
	}
	for (let i = 0; i < arr.length - 1; i += 2) {
		if (typeof(+arr[i]) !== 'number' || !Number.isNaN(+arr[i + 1])) return false
	}
	return true
}
/**
 * 中缀转后缀（逆波兰 Reverse Polish Notation）
 * @param {Array} exps - 中缀表达式数组
 */
export const toRPN = exps => {
	const s1 = [] // 符号栈
	const s2 = [] // 输出栈
	const getTopVal = (stack) => stack.length > 0 ? stack[stack.length - 1] : null
	const levelCompare = (c1, c2) => {
		const getIndex = c => ['+-', '×÷', '()'].findIndex(t => t.includes(c))
		return getIndex(c1) - getIndex(c2)
	}
	exps.forEach(t => {
		if (typeof t === 'string' && Number.isNaN(Number(t))) { // 是符号
			if (t === '(') {
				s1.push(t)
			} else if (t === ')') {
				let popVal
				do {
					popVal = s1.pop()
					popVal !== '(' && s2.push(popVal)
				} while (s1.length && popVal !== '(')
			} else {
				let topVal = getTopVal(s1)
				if (!topVal) { // s1 为空 直接push
					s1.push(t)
				} else {
					while (topVal && topVal !== '(' && levelCompare(topVal, t) >= 0) { // 优先级 >= t 弹出到s2
						s2.push(s1.pop())
						topVal = getTopVal(s1)
					}
					s1.push(t)
				}
			}
			return
		}
		s2.push(t) // 数字直接入栈
	})
	while (s1.length) {
		s2.push(s1.pop())
	}
	return s2
}
/**
 * 计算后缀表达式的值
 * @param {Array} rpnExps - 后缀表达式
 */
export const calcRPN = rpnExps => {
	rpnExps = rpnExps.concat()
	const calc = (x, y, type) => {
		let a1 = Number(x),
			a2 = Number(y)
		switch (type) {
			case '+':
				return a1 + a2;
			case '-':
				return a1 - a2;
			case '×':
				return a1 * a2;
			case '÷':
				return a1 / a2;
		}
	}
	for (let i = 2; i < rpnExps.length; i++) {
		if ('+-×÷'.includes(rpnExps[i])) {
			let val = calc(rpnExps[i - 2], rpnExps[i - 1], rpnExps[i])
			rpnExps.splice(i - 2, 3, val)
			i = i - 2
		}
	}
	return rpnExps[0]
}
/**
 * 简易防抖函数
 * @param {Function} func -防抖目标函数
 * @param {Number} gap - 防抖时间间隔
 */
export const debounce = (func, gap) => {
	let timer
	return function() {
		timer && clearTimeout(timer)
		timer = setTimeout(() => {
			func.apply(this, arguments)
		}, gap)
	}
}




//计算年或者月
export function getDateDay(Target, type, monthNum) {
	let date = new Date()
	let year = date.getFullYear() //获取当前日期的年份
	let month = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) //获取当前日期的月份
	let day = date.getDate() //获取当前日期的日
	let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
	let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
	let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
	let days = new Date(year, month, 0)
	days = days.getDate(); //获取当前日期中的月的天数
	let year2 = year;
	let month2;
	if (Target == 2) {
		if (type == 5) {
			month2 = parseInt(month) + parseInt(monthNum)
			if (month2 > 12) {
				year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12));
				month2 = parseInt(month2) % 12;
			}
		} else if (type == 4) {
			month2 = parseInt(month) - monthNum;
			if (month2 <= 0) {
				let absM = Math.abs(month2);
				year2 = parseInt(year2) - Math.ceil(absM / 12 == 0 ? 1 : parseInt(absM) / 12);
				month2 = 12 - (absM % 12);
			}
		}
	} else if (Target == 1) {
		month2 = parseInt(month)
		if (type == 5) {
			year2 = parseInt(year) + parseInt(monthNum)
		} else if (type == 4) {
			year2 = parseInt(year) - parseInt(monthNum)
		}
	}
	let day2 = day;
	let days2 = new Date(year2, month2, 0);
	days2 = days2.getDate();
	if (day2 > days2) {
		day2 = days2;
	}
	if (month2 < 10) {
		month2 = '0' + month2;
	}
	let t2 = year2 + '-' + month2 + '-' + day2 + ' ' + hours + ':' + minutes + ':' + seconds;
	return t2;
}

//计算日
export function getLaterData(days) {
	let date = new Date();
	date.setDate(date.getDate() + days);
	let month = date.getMonth() + 1;
	let day = date.getDate();
	let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
	let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
	let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
	return date.getFullYear() + '-' + ('0' + month).slice(-2) + '-' + ('0' + day).slice(-2) + ' ' + hours + ':' +
		minutes + ':' + seconds;
}
export function getBeforeData(num) {
	let dateArray = []
	//获取今天日期
	let myDate = new Date()
	let hours = myDate.getHours() < 10 ? '0' + myDate.getHours() : myDate.getHours()
	let minutes = myDate.getMinutes() < 10 ? '0' + myDate.getMinutes() : myDate.getMinutes()
	let seconds = myDate.getSeconds() < 10 ? '0' + myDate.getSeconds() : myDate.getSeconds()
	let today = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate();
	myDate.setDate(myDate.getDate() - num)
	let dateTemp; // 临时日期数据
	let flag = 1;
	for (let i = 0; i < num; i++) {
		dateTemp = myDate.getFullYear() + '-' + (myDate.getMonth() + 1) + "-" + myDate.getDate()
		dateArray.push({
			date: dateTemp
		})
		myDate.setDate(myDate.getDate() + flag);
	}
	dateArray.push({
		date: today
	})
	let arr = []
	let newArr = []
	dateArray.forEach(item => {
		arr.push(item.date.split('-'))
	})
	for (let i = 0; i < arr.length; i++) {
		if (arr[i][1] < 10) {
			arr[i][1] = "0" + arr[i][1]
		}
		if (arr[i][2] < 10) {
			arr[i][2] = "0" + arr[i][2]
		}
	}
	for (let j = 0; j < arr.length; j++) {
		newArr.push(arr[j].join("-"))
	}
	return newArr[0] + ' ' + hours + ':' + minutes + ':' + seconds
}

export function getBeforeTime(type, val) {
	let date = new Date()
	if (type == 4 || type == 1) {
		date.setHours((Number(date.getHours()) - Number(val)))
	} else if (type == 5 || type == 2) {
		date.setMinutes((Number(date.getMinutes()) - Number(val)))
	} else if (type == 6 || type == 3) {
		date.setSeconds((Number(date.getSeconds()) - Number(val)))
	}
	return date
}
export function getLaterTime(type, val) {
	let date = new Date()
	if (type == 4 || type == 1) {
		date.setHours((Number(date.getHours()) + Number(val)))
	} else if (type == 5 || type == 2) {
		date.setMinutes((Number(date.getMinutes()) + Number(val)))
	} else if (type == 6 || type == 3) {
		date.setSeconds((Number(date.getSeconds()) + Number(val)))
	}
	return date
}